package com.wushijia.java8.lambda;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.function.Function;

/**
 * description:函数式接口和函数描述符 函数式接口就是只定义一个抽象方法的接口，包含从超类中继承的方法，用@FunctionalInterface表示 Lambda表达式允许以内联的形式为函数式接口的抽象方法提供实现，并把整个表达式作为函数式接口的实例
 * 函数描述符：Lambda的签名，如：() -> void:代表了参数列表为空，返回值为void的函数
 *
 * 接口现在可以拥有默认方法，即在类没有对方法进行实现时，其主题为方法提供默认实现的方法，哪怕有很多默认方法，只要接口定义了一个抽象方法，它仍然是一个函数式接口
 *
 * @author yang
 * @date 2018/4/26 20:31
 */
public class Chapter2 {

  Runnable runnable = () -> System.out.println();

  //processFile方法对文件做不同的操作，把processFile的行为参数化，需要接收一个BufferedReader，函数描述符：BufferedReader -> String
  public static String processFile() throws IOException {
    try (BufferedReader br = new BufferedReader(new FileReader("test.text"))) {
      return br.readLine();
    }
  }

  public static String processFile_new(BufferedReaderProcess p, String file) throws IOException {
    try (BufferedReader bufferedReader = new BufferedReader(new FileReader(file))) {
      return p.process(bufferedReader);
    }
  }

  /*public static int test(String s){
    return Integer :: parseInt;
  }*/

  public static void main(String[] args) throws IOException {

    //方法引用简写
    //String oneLIne = processFile_new(BufferedReader::readLine, "test.text");

    //String twoLine = processFile_new((BufferedReader bf) -> bf.readLine() + bf.readLine(), "test.text");

    //函数式接口
    //Predicate：接受一个泛型T对象，返回一个boolean
    //Consumer；接受一个泛型T对象，并返回void
    //Function<T,R>：定义了一个apply的方法，接受一个泛型T的对象，并返回一个泛型R的对象
    //任何函数式接口都不允许抛出受检异常，如果需要Lambda抛出异常：1、自定义一个函数式接口，并声明受检异常 2、把lambda包在一个try/catch块中
    Function<BufferedReader, String> function = (BufferedReader b) -> {
      try {
        return b.readLine();
      } catch (IOException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
      }
    };

    //同样的lambda，不同的函数式接口：同一个lambda表达式可以与不同的函数式接口联系起来，只要它们的抽象方法签名能够兼容
    Callable<Integer> callable = () -> 42;
    PrivilegedAction<Integer> privilegedAction = () -> 42;

    List<String> list = Arrays.asList("a","b","A","B");
    list.sort((s1,s2) -> s1.compareToIgnoreCase(s2));
    System.out.println(list);

    list.sort(String :: compareToIgnoreCase);
    System.out.println(list);


  }


}
